﻿global using Devonline.Core;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

namespace Devonline.Utils;

public static class ImageUtility
{
    /// <summary>
    /// 制作缩略图, 不校验图片文件类型
    /// </summary>
    /// <param name="fileName">文件名</param>
    public static async Task CreateDefaultThumbnailAsync(this string fileName)
    {
        if (!File.Exists(fileName))
        {
            throw new FileNotFoundException("原文件不存在!", fileName);
        }

        using var fileStream = File.OpenRead(fileName);
        using var image = await Image.LoadAsync(fileStream);
        await image.CreateThumbnailAsync(AppSettings.DEFAULT_IMAGE_THUMBNAIL_SIZE, AppSettings.DEFAULT_IMAGE_THUMBNAIL_SIZE, AppSettings.DEFAULT_IMAGE_THUMBNAIL_PREFIX + Path.GetFileName(fileName));
    }
    /// <summary>
    /// 制作图片文件缩略图, 不校验图片文件类型
    /// </summary>
    /// <param name="fileName">图片对象</param>
    /// <param name="width">最大宽度</param>
    /// <param name="height">最大高度</param>
    /// <param name="thumbnailName">新图路径</param>
    public static async Task CreateThumbnailAsync(this string fileName, int width, int height, string thumbnailName)
    {
        if (!File.Exists(fileName))
        {
            throw new FileNotFoundException("文件不存在!", fileName);
        }

        using var fileStream = File.OpenRead(fileName);
        using var image = await Image.LoadAsync(fileStream);
        await image.CreateThumbnailAsync(width, height, thumbnailName);
    }
    /// <summary>
    /// 制作缩略图
    /// </summary>
    /// <param name="original">图片对象</param>
    /// <param name="width">最大宽度</param>
    /// <param name="height">最大高度</param>
    /// <param name="thumbnailName">新图路径</param>
    public static async Task CreateThumbnailAsync(this Image original, int width, int height, string thumbnailName)
    {
        try
        {
            var newSize = ResizeImage(original.Width, original.Height, width, height);
            using var image = original.CloneAs<Rgba32>();
            image.Mutate(x => x.Resize(newSize));
            await image.SaveAsync(thumbnailName);
        }
        finally
        {
            original.Dispose();
        }
    }

    /// <summary>
    /// 计算新尺寸
    /// </summary>
    /// <param name="width">原始宽度</param>
    /// <param name="height">原始高度</param>
    /// <param name="maxWidth">最大新宽度</param>
    /// <param name="maxHeight">最大新高度</param>
    /// <returns></returns>
    private static Size ResizeImage(int width, int height, int maxWidth, int maxHeight)
    {
        if (maxWidth <= 0)
        {
            maxWidth = width;
        }

        if (maxHeight <= 0)
        {
            maxHeight = height;
        }

        float MAX_WIDTH = maxWidth;
        float MAX_HEIGHT = maxHeight;
        var ASPECT_RATIO = MAX_WIDTH / MAX_HEIGHT;

        int newWidth, newHeight;
        float originalWidth = width;
        float originalHeight = height;

        if (originalWidth > MAX_WIDTH || originalHeight > MAX_HEIGHT)
        {
            float factor;
            if (originalWidth / originalHeight > ASPECT_RATIO)
            {
                factor = originalWidth / MAX_WIDTH;
                newWidth = Convert.ToInt32(originalWidth / factor);
                newHeight = Convert.ToInt32(originalHeight / factor);
            }
            else
            {
                factor = originalHeight / MAX_HEIGHT;
                newWidth = Convert.ToInt32(originalWidth / factor);
                newHeight = Convert.ToInt32(originalHeight / factor);
            }
        }
        else
        {
            newWidth = width;
            newHeight = height;
        }

        return new Size(newWidth, newHeight);
    }
}